﻿using Koala.Pro.Common;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;

namespace Koala.Pro.Helpers
{
    public sealed class EncryptHelper
    {
        public const string DEFAULT_ENCRYPT_KEY = "dcf2bc425f5a";

        private static readonly string Default_AES_Key = "K7bR4pQ6zW";

        private static byte[] Keys =
        [
            65, 114, 101, 121, 111, 117, 109, 121, 83, 110,
            111, 119, 109, 97, 110, 63
        ];

        public static string DesEncrypt(string strText)
        {
            try
            {
                return DesEncrypt(strText, DEFAULT_ENCRYPT_KEY);
            }
            catch
            {
                return "";
            }
        }

        public static string DesDecrypt(string strText)
        {
            try
            {
                return DesDecrypt(strText, DEFAULT_ENCRYPT_KEY);
            }
            catch
            {
                return "";
            }
        }

        public static string DesEncrypt(string strText, string strEncrKey)
        {
            byte[] array = null;
            byte[] rgbIV = new byte[8] { 18, 52, 86, 120, 144, 171, 205, 239 };
            array = Encoding.UTF8.GetBytes(strEncrKey.Substring(0, 8));
            DESCryptoServiceProvider dESCryptoServiceProvider = new DESCryptoServiceProvider();
            byte[] bytes = Encoding.UTF8.GetBytes(strText);
            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memoryStream, dESCryptoServiceProvider.CreateEncryptor(array, rgbIV), CryptoStreamMode.Write);
            cryptoStream.Write(bytes, 0, bytes.Length);
            cryptoStream.FlushFinalBlock();
            return Convert.ToBase64String(memoryStream.ToArray());
        }

        public static string DesDecrypt(string strText, string sDecrKey)
        {
            byte[] array = null;
            byte[] rgbIV = new byte[8] { 18, 52, 86, 120, 144, 171, 205, 239 };
            byte[] array2 = new byte[strText.Length];
            array = Encoding.UTF8.GetBytes(sDecrKey.Substring(0, 8));
            DESCryptoServiceProvider dESCryptoServiceProvider = new DESCryptoServiceProvider();
            array2 = Convert.FromBase64String(strText);
            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memoryStream, dESCryptoServiceProvider.CreateDecryptor(array, rgbIV), CryptoStreamMode.Write);
            cryptoStream.Write(array2, 0, array2.Length);
            cryptoStream.FlushFinalBlock();
            return new UTF8Encoding().GetString(memoryStream.ToArray());
        }

        public static void DesEncrypt(string m_InFilePath, string m_OutFilePath, string strEncrKey)
        {
            byte[] array = null;
            byte[] rgbIV = new byte[8] { 18, 52, 86, 120, 144, 171, 205, 239 };
            array = Encoding.UTF8.GetBytes(strEncrKey.Substring(0, 8));
            FileStream fileStream = new FileStream(m_InFilePath, FileMode.Open, FileAccess.Read);
            FileStream fileStream2 = new FileStream(m_OutFilePath, FileMode.OpenOrCreate, FileAccess.Write);
            fileStream2.SetLength(0L);
            byte[] buffer = new byte[100];
            long num = 0L;
            long length = fileStream.Length;
            DES dES = new DESCryptoServiceProvider();
            CryptoStream cryptoStream = new CryptoStream(fileStream2, dES.CreateEncryptor(array, rgbIV), CryptoStreamMode.Write);
            int num2;
            for (; num < length; num += num2)
            {
                num2 = fileStream.Read(buffer, 0, 100);
                cryptoStream.Write(buffer, 0, num2);
            }
            cryptoStream.Close();
            fileStream2.Close();
            fileStream.Close();
        }

        public static void DesDecrypt(string m_InFilePath, string m_OutFilePath, string sDecrKey)
        {
            byte[] array = null;
            byte[] rgbIV = new byte[8] { 18, 52, 86, 120, 144, 171, 205, 239 };
            array = Encoding.UTF8.GetBytes(sDecrKey.Substring(0, 8));
            FileStream fileStream = new FileStream(m_InFilePath, FileMode.Open, FileAccess.Read);
            FileStream fileStream2 = new FileStream(m_OutFilePath, FileMode.OpenOrCreate, FileAccess.Write);
            fileStream2.SetLength(0L);
            byte[] buffer = new byte[100];
            long num = 0L;
            long length = fileStream.Length;
            DES dES = new DESCryptoServiceProvider();
            CryptoStream cryptoStream = new CryptoStream(fileStream2, dES.CreateDecryptor(array, rgbIV), CryptoStreamMode.Write);
            int num2;
            for (; num < length; num += num2)
            {
                num2 = fileStream.Read(buffer, 0, 100);
                cryptoStream.Write(buffer, 0, num2);
            }
            cryptoStream.Close();
            fileStream2.Close();
            fileStream.Close();
        }

        public static string AES_Encrypt(string encryptString)
        {
            return AES_Encrypt(encryptString, Default_AES_Key);
        }

        public static string AES_Encrypt(string encryptString, string encryptKey)
        {
            encryptKey = GetSubString(encryptKey, 32, "");
            encryptKey = encryptKey.PadRight(32, ' ');
            ICryptoTransform cryptoTransform = new RijndaelManaged
            {
                Key = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 32)),
                IV = Keys
            }.CreateEncryptor();
            byte[] bytes = Encoding.UTF8.GetBytes(encryptString);
            return Convert.ToBase64String(cryptoTransform.TransformFinalBlock(bytes, 0, bytes.Length));
        }

        public static string AES_Decrypt(string decryptString)
        {
            return AES_Decrypt(decryptString, Default_AES_Key);
        }

        public static string AES_Decrypt(string decryptString, string decryptKey)
        {
            try
            {
                decryptKey = GetSubString(decryptKey, 32, "");
                decryptKey = decryptKey.PadRight(32, ' ');
                ICryptoTransform cryptoTransform = new RijndaelManaged
                {
                    Key = Encoding.UTF8.GetBytes(decryptKey),
                    IV = Keys
                }.CreateDecryptor();
                byte[] array = Convert.FromBase64String(decryptString);
                byte[] bytes = cryptoTransform.TransformFinalBlock(array, 0, array.Length);
                return Encoding.UTF8.GetString(bytes);
            }
            catch
            {
                return string.Empty;
            }
        }

        private static string GetSubString(string sourceString, int length, string tailString)
        {
            return GetSubString(sourceString, 0, length, tailString);
        }

        private static string GetSubString(string sourceString, int startIndex, int length, string tailString)
        {
            if (Regex.IsMatch(sourceString, "[ࠀ-一]+") || Regex.IsMatch(sourceString, "[가-힣]+"))
            {
                if (startIndex >= sourceString.Length)
                {
                    return string.Empty;
                }
                return sourceString.Substring(startIndex, (length + startIndex > sourceString.Length) ? (sourceString.Length - startIndex) : length);
            }
            if (length <= 0)
            {
                return string.Empty;
            }
            byte[] bytes = Encoding.Default.GetBytes(sourceString);
            if (bytes.Length > startIndex)
            {
                int num = bytes.Length;
                if (bytes.Length > startIndex + length)
                {
                    num = length + startIndex;
                }
                else
                {
                    length = bytes.Length - startIndex;
                    tailString = "";
                }
                int[] array = new int[length];
                int num2 = 0;
                for (int i = startIndex; i < num; i++)
                {
                    if (bytes[i] > 127)
                    {
                        num2++;
                        if (num2 == 3)
                        {
                            num2 = 1;
                        }
                    }
                    else
                    {
                        num2 = 0;
                    }
                    array[i] = num2;
                }
                if (bytes[num - 1] > 127 && array[length - 1] == 1)
                {
                    length++;
                }
                byte[] array2 = new byte[length];
                Array.Copy(bytes, startIndex, array2, 0, length);
                return Encoding.Default.GetString(array2) + tailString;
            }
            return string.Empty;
        }

        public static CryptoStream AES_EncryptStrream(FileStream fs, string encryptKey)
        {
            encryptKey = GetSubString(encryptKey, 32, "");
            encryptKey = encryptKey.PadRight(32, ' ');
            ICryptoTransform transform = new RijndaelManaged
            {
                Key = Encoding.UTF8.GetBytes(encryptKey),
                IV = Keys
            }.CreateEncryptor();
            return new CryptoStream(fs, transform, CryptoStreamMode.Write);
        }

        public static CryptoStream AES_DecryptStream(FileStream fs, string decryptKey)
        {
            decryptKey = GetSubString(decryptKey, 32, "");
            decryptKey = decryptKey.PadRight(32, ' ');
            ICryptoTransform transform = new RijndaelManaged
            {
                Key = Encoding.UTF8.GetBytes(decryptKey),
                IV = Keys
            }.CreateDecryptor();
            return new CryptoStream(fs, transform, CryptoStreamMode.Read);
        }

        public static bool AES_EncryptFile(string InputFile, string OutputFile)
        {
            try
            {
                string encryptKey = "www.iqidi.com";
                FileStream fileStream = new FileStream(InputFile, FileMode.Open);
                FileStream fileStream2 = new FileStream(OutputFile, FileMode.Create);
                CryptoStream cryptoStream = AES_EncryptStrream(fileStream2, encryptKey);
                byte[] array = new byte[fileStream.Length];
                fileStream.Read(array, 0, array.Length);
                cryptoStream.Write(array, 0, array.Length);
                cryptoStream.Close();
                fileStream.Close();
                fileStream2.Close();
            }
            catch
            {
                return false;
            }
            return true;
        }

        public static bool AES_DecryptFile(string InputFile, string OutputFile)
        {
            try
            {
                string decryptKey = "www.iqidi.com";
                FileStream fileStream = new FileStream(InputFile, FileMode.Open);
                FileStream fileStream2 = new FileStream(OutputFile, FileMode.Create);
                CryptoStream cryptoStream = AES_DecryptStream(fileStream, decryptKey);
                byte[] array = new byte[1024];
                int num = 0;
                do
                {
                    num = cryptoStream.Read(array, 0, array.Length);
                    fileStream2.Write(array, 0, num);
                }
                while (num >= array.Length);
                cryptoStream.Close();
                fileStream.Close();
                fileStream2.Close();
            }
            catch
            {
                return false;
            }
            return true;
        }

        public static string Base64Encrypt(string str)
        {
            return Convert.ToBase64String(Encoding.UTF8.GetBytes(str));
        }

        public static string Base64Decrypt(string str)
        {
            byte[] bytes = Convert.FromBase64String(str);
            return Encoding.UTF8.GetString(bytes);
        }

        public static string MD5Encrypt(string strText)
        {
            byte[] bytes = new MD5CryptoServiceProvider().ComputeHash(Encoding.Default.GetBytes(strText));
            return Encoding.Default.GetString(bytes);
        }

        public static string MD5EncryptHash(string input)
        {
            byte[] array = new MD5CryptoServiceProvider().ComputeHash(Encoding.Default.GetBytes(input), 0, input.Length);
            char[] array2 = new char[array.Length];
            Array.Copy(array, array2, array.Length);
            return new string(array2);
        }

        public static string MD5EncryptHashHex(string input)
        {
            byte[] array = new MD5CryptoServiceProvider().ComputeHash(Encoding.Default.GetBytes(input), 0, input.Length);
            string text = string.Empty;
            for (int i = 0; i < array.Length; i++)
            {
                text += Uri.HexEscape((char)array[i]);
            }
            text = text.Replace("%", "");
            return text.ToLower();
        }

        public static string EncyptMD5_3_16(string s)
        {
            MD5 mD = MD5.Create();
            byte[] bytes = Encoding.ASCII.GetBytes(s);
            byte[] buffer = mD.ComputeHash(bytes);
            byte[] buffer2 = mD.ComputeHash(buffer);
            byte[] array = mD.ComputeHash(buffer2);
            StringBuilder stringBuilder = new StringBuilder();
            byte[] array2 = array;
            foreach (byte b in array2)
            {
                stringBuilder.Append(b.ToString("x").PadLeft(2, '0'));
            }
            return stringBuilder.ToString().ToUpper();
        }

        public static string SHA256(string str)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(str);
            return Convert.ToBase64String(new SHA256Managed().ComputeHash(bytes));
        }

        public static string EncryptString(string input)
        {
            return MD5Util.AddMD5Profix(Base64Util.Encrypt(MD5Util.AddMD5Profix(input)));
        }

        public static string DecryptString(string input, bool throwException)
        {
            string text = "";
            try
            {
                text = input;
                if (MD5Util.ValidateValue(text))
                {
                    return MD5Util.RemoveMD5Profix(Base64Util.Decrypt(MD5Util.RemoveMD5Profix(text)));
                }
                throw new Exception("字符串无法转换成功！");
            }
            catch
            {
                if (throwException)
                {
                    throw;
                }
                return "";
            }
        }

        public static string ComputeHash(string source, string key)
        {
            if (source == null)
            {
                return "";
            }
            string text = "abcdefghjklmnopqrstuvwxyz";
            if (source.Length < 26)
            {
                source += text.Substring(source.Length);
            }
            byte[] bytes = Encoding.Unicode.GetBytes(source);
            int num = bytes.Length;
            if (key == null || key.Length == 0)
            {
                key = "6fd501fc-64a7-42f2-9ad8-dcf2bc425f5a";
            }
            byte[] bytes2 = Encoding.Unicode.GetBytes(key);
            byte b = Convert.ToByte(bytes2.Length);
            byte b2 = 2;
            byte b3 = 0;
            for (int i = 0; i < num; i++)
            {
                byte b4 = (byte)(bytes2[b3] | b);
                b4 &= b2;
                byte[] array;
                IntPtr intPtr;
                (array = bytes)[(int)(intPtr = (IntPtr)i)] = (byte)(array[(int)intPtr] ^ b4);
                b2++;
                if (b2 > 253)
                {
                    b2 = 2;
                }
                b3++;
                if (b3 >= b)
                {
                    b3 = 0;
                }
            }
            return Convert.ToBase64String(bytes, 0, bytes.Length);
        }

        public static string EncryptStr(string source, string key)
        {
            key = key.PadLeft(8, 'x');
            return DesEncrypt(source, key);
        }

        public static string UnEncryptStr(string source, string key)
        {
            key = key.PadLeft(8, 'x');
            return DesDecrypt(source, key);
        }
    }
}
